Kurt Hsu's blog

The Rails developer in taiwan.


  • 首頁

  • 標籤

  • 分類

  • 歸檔

[Rails]rails 搭配 vue-router(目前無法指定vue-routes)

發表於 2018-05-12 更新於 2019-08-21 分類於 Rails , Vue

參考文件:
webpacker

Rails版本5.1以上可以直接創造帶有webpack的新專案
$ rails new rails-vue-todolist --skip-turbolinks --skip-spring --webpack=vue
$ cd rails-vue-todolist

先快速建立todolist
$ rails g scaffold Todolist item:string
$ bundle install

設定router

routes.rb
1
root "todolists#index"

測試有沒有成功

app/views/layout/application.html.erb
1
<%= javascript_pack_tag 'hello_vue' %>

更新todolist/index

app/views/todolists/index.html.erb
1
2
<div id="hello"></div>
...

$ rails s
到首頁刷新頁面應該就會有了,如果有出現:
You may need an appropriate loader to handle this file type.
可以嘗試下下面三個指令
$ bundle update webpacker
$ yarn upgrade @rails/webpacker
$ bundle exec rails webpacker:install:vue

大多會是版本上的問題,如果直接用rails5.1以上應該沒有問題,如果是用其他版本或者是專案升級情況可能要再去查詢下官方log文件。

再來如果玩過Vue.js的人有一種開發模式是把一個id=”app”當作入口,所以我們會有一個主要的main.js和主要生成vue的app.vue,此時app/javascript/packs/application.js可以把它當作main.js,再來怎麼規劃檔案就都可以了。

我們循著上面的作法先改rails view剛剛的application.html.erb的tag

app/views/layout/application.html.erb
1
2
3
# 把原本的 <%= javascript_pack_tag 'hello_vue' %> 替換如下

<%= javascript_pack_tag 'application' %>

修改index入口點只留下一行當作vue的入口就好

app/views/todolists/index.html.erb
1
<div id="app"></div>

修改packs/application.js

app/javascript/packs/application.js
1
2
3
4
5
6
7
8
9
import Vue from 'vue'
import App from '../app.vue'

document.addEventListener('DOMContentLoaded', () => {
const app = new Vue({
el: "#app",
render: h => h(App)
})
})

現在再重新刷新一次頁面如果有render出Hello Vue!恭喜已經設定好所有一切了!

初創index


接下來我們先直接在app.vue裡面創造假資料做出index畫面:

app/javascript/app.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<template>
<div>
<h1>Todo Lists</h1>
<table>
<thead>
<tr>
<th>#</th>
<th>Item</th>
</tr>
</thead>

<tbody>
<tr v-for="todo in list" >
<td>{{ todo.id }}</td>
<td>{{ todo.item }}</td>
</tr>
</tbody>
</table>
</div>
</template>

<script>
export default {
data: function () {
return {
list: [
{ id: 1, item: "Foo" },
{ id: 2, item: "Bar" }
]
}
}
}
</script>

應該會list出兩個item出來,但我們要去拿rails裡todolists#index的資料,首先我們在rails console新增兩筆:
$ rails c
$ Todolist.create(item: "Test1")
$ Todolist.create(item: "Test2")
$ exit

然後如何從vue的methods裡面拿取資料,可以用vue-resource這個套件。
$ yarn add vue-resource

然後import在app/javascript/application.js裡:

app/javascript/application.js
1
2
import VueResource from 'vue-resource'
Vue.use(VueResource);

現在修改app.vue

app/javascript/app.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<template>
<div>
<h1>Todo Lists</h1>
<table>
<thead>
<tr>
<th>#</th>
<th>Item</th>
</tr>
</thead>

<tbody>
<tr v-for="todo in list" >
<td>{{ todo.id }}</td>
<td>{{ todo.item }}</td>
</tr>
</tbody>
</table>
</div>
</template>

<script>
export default {
data: function () {
return {
list: []
}
},

created: function() {
this.fetchTodoLists();
},

methods: {
fetchTodoLists: function() {
const resource = this.$resource('/todolists.json');
resource.get()
.then(response => {
this.list = response.data
});
}
}
}
</script>

應該會出現剛剛在console創的兩筆資料。

component裡面寫css


在webpacker官方文件裡面有規劃資料夾,雖然敘述說會有放js css images的地方但我初創的時候只有放js的資料夾,他的架構如下:
app/javascript:
├── packs:
│ # only webpack entry files here
│ └── application.js
└── src:
│ └── application.css
└── images:
└── logo.svg

照著他的架構創
$ mkdir app/javascript/src
$ touch app/javascript/src/application.css

然後在原本rails的application.html.erb加上連結

app/views/layouts/application.html.erb
1
<%= stylesheet_pack_tag 'application' %>

就可以在每個.vue檔的component裡面寫css了,例如:

component.vue
1
2
3
4
5
6
<style lang="scss">
.link {
color: blue;
cursor: pointer;
}
</style>

引入vue-router


再來跟全端開發一樣,rails的gem歸rails的Gemfile,而webpack的歸package.json(Vue也是在這裡面,只不過rails5.1連著專案一起創webpack的話已經內建Vue了!)。

現在安裝vue-router
$ yarn add vue-router

先把router寫在一個js裡面:
$ touch app/javascript/packs/router.js
建立routes

app/javascript/packs/router.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import Vue from 'vue'

import VueRouter from 'vue-router'
Vue.use(VueRouter)

import todolists_index from './../views/todolist/index.vue'

const router = new VueRouter({
// 使用 HTML 5 模式
mode: 'history',
routes: [
{ path: '/todolists', component: todolists_index },
{ path: '/', redirect: '/todolists' }
]
})

export default router

檔名或變數不要取routes避免產生match error

修改packs/application.js把

app/javascript/packs/application.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import Vue from 'vue'
import App from '../app.vue'

import VueResource from 'vue-resource'
Vue.use(VueResource);

import VueRouter from 'vue-router'
Vue.use(VueRouter)
import router from './router.js'

document.addEventListener('DOMContentLoaded', () => {
const app = new Vue({
el: "#app",
router,
render: h => h(App)
})
})

現在創造專給vue的view的資料夾
$ mkdir app/javascript/views
再給todolist一個歸類
$ mkdir app/javascript/views/todolist
最後先做index檔案,根本來的app.vue一模一樣
$ cp app/javascript/app.vue app/javascript/views/todolist/index.vue

最後app.vue簡化如下:

app/javascript/app.vue
1
2
3
4
5
6
7
8
9
10
11
<template>
<div>
<router-view></router-view>
</div>
</template>

<script>
export default {
name: 'app'
}
</script>

就成功import vue-router了!這樣也算是做出前後端分離的概念了,rails去吐api,而vue就專門做前端的東西吧!

但目前遇到的問題是重整頁面會去讀取rilas routes,要怎麼設定待研究

# Rails # Vue # vue-router
[Rails]RSpec101
[Rails]專案引入vue & 利用Attribute給 vue 資料
  • 文章目錄
  • 本站概要

Kurt Hsu

Progress One Percent Every Day
171 文章
55 分類
163 標籤
RSS
  1. 1. 初創index
  2. 2. component裡面寫css
  3. 3. 引入vue-router
  4. 4. 但目前遇到的問題是重整頁面會去讀取rilas routes,要怎麼設定待研究
© 2020 Kurt Hsu
由 Hexo 強力驅動 v3.8.0
|
主題 – NexT.Muse v7.3.0